#ifndef __MARS_GRAPHICS_RENDERER_H__
#define __MARS_GRAPHICS_RENDERER_H__

#include <stack>

#include "MarsType.h"

namespace Graphics
{

class RenderTarget;

class Renderer
{
public:
	virtual							~Renderer();

	bool							Initialize( HINSTANCE hInstance, HWND hwnd );
	void							Shutdown();

	static Renderer&				Instance();
	static void						Destroy();

	ID3D11Device*					GetDevice();
	ID3D11DeviceContext*			GetDeviceContext();

	bool							IsReady() const;
	void							ClearRenderTarget( const float colorRGBA[ 4 ] );
	void							ClearDepthStencil( float fDepthValue, Core::uint8 iStencilValue );
	void							Present();

	Core::uint32					GetWindowWidth() const;
	Core::uint32					GetWindowHeight() const;

	void							PushRenderTarget( RenderTarget* pRenderTarget );
	RenderTarget*					PopRenderTarget();							

private:
									Renderer();
									Renderer( const Renderer& );
	Renderer&						operator = ( const Renderer& );

	static Renderer*				ms_pRenderer;

	HINSTANCE						m_hInstance;
	HWND							m_hwnd;

	Core::uint32					m_iWindowWidth;
	Core::uint32					m_iWindowHeight;

	D3D_DRIVER_TYPE					m_driverType;
	D3D_FEATURE_LEVEL				m_featureLevel;

	ID3D11Device*					m_pD3dDevice;
	ID3D11DeviceContext*			m_pD3dContext;
	IDXGISwapChain*					m_pSwapChain;
	ID3D11RenderTargetView*			m_pBackBufferTargetView;
	ID3D11Texture2D*				m_pDepthTexture;
	ID3D11DepthStencilView*			m_pDepthStencilView;

	std::stack< RenderTarget* >		m_renderTargets;
};

inline Renderer& Renderer::Instance()
{
	if ( !ms_pRenderer )
	{
		ms_pRenderer = new Renderer();
	}

	return ( *ms_pRenderer );
}

inline ID3D11Device* Renderer::GetDevice()
{
	return m_pD3dDevice;
}

inline ID3D11DeviceContext* Renderer::GetDeviceContext()
{
	return m_pD3dContext;
}

inline bool Renderer::IsReady() const
{
	return ( m_pD3dContext != 0 );
}

inline Core::uint32 Renderer::GetWindowWidth() const
{
	return m_iWindowWidth;
}

inline Core::uint32 Renderer::GetWindowHeight() const
{
	return m_iWindowHeight;
}

} // end of namespace Graphics

#endif // end of #ifndef __MARS_GRAPHICS_RENDERER_H__